package com.sj.excel;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author longbing
 * @create 2021-04-10-11:38
 */
public class ExcelToDto {

    //资源绝对路径
    public static String xlsPath = "F:\\文档\\实体类\\黑名单.xls";
    //资源的目录
    public static String dirPath = "E:\\code\\thread\\src\\main\\java\\com\\sj\\excel\\file\\";
    //输出路径
    public static String javaPath = "";
    //字段名列
    public static int attributesIndex = 1;
    //类型列
    public static int typesIndex = 3;
    //注释列
    public static int[] marksIndex = {2, 7};
    //注释列
    public static int notNullIndex = 6;

    //输出类型
    public static String classType = "in";
//    public static String classType = "out";

    //是否为空注释
    // public static int marksEmptyIndex=3;
    public static void main(String[] args) throws IOException, InvalidFormatException {
// TODO Auto-generated method stub
        File file = new File(dirPath);
        ArrayList<File> files = getListFiles(file);
        for (File f : files) {
            createJAVA(f);
        }

    }

    /**
     * 创建实体类
     * @param file
     * @throws IOException
     * @throws InvalidFormatException
     */
    public static void createJAVA(File file) throws IOException, InvalidFormatException {

        String fileName = file.getName();
        String name = fileName.substring(0, fileName.lastIndexOf("."));
        String className;
        if ("in".equals(classType)) {
            className = "Fmi" + name + "InputDTO";
        }else {
            className = "Fmi" + name + "OutputDTO";
        }
        File file1;
        FileOutputStream fop;
        List types = new ArrayList();
        List attributes = new ArrayList();
        List notNulls = new ArrayList();
        List marks = new ArrayList();
// List marksEmpty = new ArrayList();
        if (fileName.endsWith("xlsx")) {
            XSSFWorkbook workbooks = new XSSFWorkbook(FileUtils.openInputStream(file));
            XSSFSheet xssfSheet = workbooks.getSheetAt(0);
            int totalRows = xssfSheet.getPhysicalNumberOfRows();
            System.out.println(className + "total:" + totalRows);
            for (int i = 1; i <= totalRows; i++) {
                XSSFRow row2 = xssfSheet.getRow(i);
                attributes.add(row2.getCell(attributesIndex).getStringCellValue());
                types.add(getObjType(row2.getCell(typesIndex).getStringCellValue()));
                String marksDtr = "";
                for (int j = marksIndex.length - 1; j >= 0; j--) {
                    marksDtr += row2.getCell(marksIndex[j]).getStringCellValue();
                }
                marks.add(marksDtr);
            }

        } else if (fileName.endsWith("xls")) {
            HSSFWorkbook workbook = new HSSFWorkbook(FileUtils.openInputStream(file));
//读取默认第一个工作表sheet
            HSSFSheet sheet = workbook.getSheetAt(0);
//获取sheet中最后一行行号
            int lastRowNum = sheet.getLastRowNum();
            for (int i = 1; i <= lastRowNum - 1; i++) {
                HSSFRow row1 = sheet.getRow(i);
                attributes.add(row1.getCell(attributesIndex).getStringCellValue());
                types.add(getObjType(row1.getCell(typesIndex).getStringCellValue()));
                notNulls.add(getObjType(row1.getCell(notNullIndex).getStringCellValue()));
                String marksDtr = "";
                for (int j = marksIndex.length - 1, k = 0; j >= 0; j--, k++) {
                    String stringCellValue = row1.getCell(marksIndex[k]).getStringCellValue();
                    if (j == marksIndex.length - 1){
                        marksDtr = stringCellValue;
                    } else if (StringUtils.isNotBlank(stringCellValue)){
                        marksDtr += "-->" + stringCellValue;
                    }
                }
                marks.add(marksDtr);
//marksEmpty.add(row1.getCell(marksEmptyIndex).getStringCellValue());
            }
        }

        StringBuffer sb = new StringBuffer();
        if ("out".equals(classType)) {
            try {
                List oa = new ArrayList();
                CollectionUtils.addAll(oa, new Object[attributes.size()]);
                Collections.copy(oa, attributes);
                attributes = CreateUtil.attributesFilter(attributes);
                types = CreateUtil.typesFilter(types);
//                sb.append("//引用、包名、注释等等\n");
                sb.append("@Data\n");
                sb.append("public class " + className + " implements Serializable {\n\n");
                sb.append("private static final long serialVersionUID = 1L;\n\n");
                sb.append("private List<Result> result;\n\n");
                sb.append("@Data\n");
                sb.append("public static class Result implements Serializable {\n\n");
                sb.append("private static final long serialVersionUID = 1L;\n\n");

                sb.append(CreateUtil.appendPrivate(types, attributes, marks, oa,notNulls));
                //以下是getset方法
                //sb.append(createUtil.getSet(types, attributes, marks));
                sb.append("}\n");
                sb.append("}");
            } catch (Exception e) {
                System.out.println(e.toString());
            }
        } else {
            try {
                List oa = new ArrayList();
                CollectionUtils.addAll(oa, new Object[attributes.size()]);
                Collections.copy(oa, attributes);
                attributes = CreateUtil.attributesFilter(attributes);
                types = CreateUtil.typesFilter(types);
                sb.append("//引用、包名、注释等等\n");
                sb.append("@Data\n");
                sb.append("public class " + className + " implements Serializable {\n\n");
                sb.append("private static final long serialVersionUID = 1L;\n\n");
                sb.append("private Data data;\n\n");
                sb.append("@lombok.Data\n");
                sb.append("public static class Data implements Serializable {\n\n");
                sb.append("private static final long serialVersionUID = 1L;\n\n");
                sb.append(CreateUtil.appendPrivate(types, attributes, marks, oa, notNulls));
                //以下是getset方法
                //sb.append(createUtil.getSet(types, attributes, marks));
                sb.append("}\n");
                sb.append("}");
            } catch (Exception e) {
                System.out.println(e.toString());
            }
        }

        file1 = new File(file.getParent() + "//" + className + ".java");
        fop = new FileOutputStream(file1);
        if (!file1.exists()) {
            file1.createNewFile();
        }
        byte[] contentInBytes = sb.toString().getBytes();
        fop.write(contentInBytes);
        fop.flush();
        fop.close();
        System.out.println("Done");
    }

    private static Object getObjType(String stringCellValue) {
        if ("字符型".equals(stringCellValue)){
            return "String";
        }
        if ("日期型".equals(stringCellValue)){
            return "LocalDate";
        }
        if ("日期时间型".equals(stringCellValue)){
            return "LocalDateTime";
        }
        if ("数值型".equals(stringCellValue)){
            return "BigDecimal";
        }
        return stringCellValue;
    }

    public static ArrayList getListFiles(Object obj) {
        File directory = null;
        if (obj instanceof File) {
            directory = (File) obj;
        } else {
            directory = new File(obj.toString());
        }
        ArrayList files = new ArrayList();
        if (directory.isFile()) {
            files.add(directory);
            return files;
        } else if (directory.isDirectory()) {
            File[] fileArr = directory.listFiles();
            for (int i = 0; i < fileArr.length; i++) {
                File fileOne = fileArr[i];
                files.addAll(getListFiles(fileOne));
            }

        }
        return files;
    }
}
